package game.editer;

import hx.events.Event;
import game.editer.history.ChangeAttr;
import hx.display.VBox;
import game.editer.ui.InputCreater;
import game.editer.ui.IAttributeInput;
import hx.layout.AnchorLayoutData;
import hx.display.Scroll;
import game.editer.ui.BaseAttributeInput;

/**
 * 属性编辑器
 */
class AttrEditer extends BasePanel {
	public var attrs:Array<AttrData>;

	public var attributeDisplayObjects:Map<String, BaseAttributeInput> = [];

	public var vbox:VBox;

	public var editData:Dynamic;

	public function new() {
		this.width = 200;
		super("属性");
	}

	override function onInit() {
		super.onInit();
		var scroll = new Scroll();
		this.addChild(scroll);
		scroll.layoutData = new AnchorLayoutData(36, 0, 3, 0);
		vbox = new VBox();
		vbox.x = 10;
		scroll.addChild(vbox);
	}

	/**
	 * 绑定编辑数据
	 * @param title 
	 * @param data 
	 * @param attrs 
	 */
	public function bindEditData(title:String, data:Dynamic, attrs:Array<AttrData>):Void {
		this.title = title;
		this.label.data = title;
		this.editData = data;
		this.attrs = attrs;
		vbox.removeChildren();
		if (attrs == null) {
			return;
		}
		for (i in 0...attrs.length) {
			var attr = attrs[i];
			var idKey = title + "_" + attr.key;
			var input:BaseAttributeInput = attributeDisplayObjects.exists(idKey) ? attributeDisplayObjects.get(idKey) : InputCreater.create(attr,
				onAttributeChange);
			attributeDisplayObjects.set(idKey, input);
			var v2 = attr.key == "self" ? data : Reflect.getProperty(data, attr.key);
			var v = v2 != null ? switch attr.type {
				case Number:
					Math.round(v2 * 100) / 100; // 保留两位小数
				default:
					v2;
			} : v2;
			if (v == null && attr.key.indexOf("origin") != -1) {
				v = switch attr.type {
					case Number:
						Math.round(Reflect.getProperty(data, "_" + attr.key) * 100) / 100; // 保留两位小数
					default:
						Reflect.getProperty(data, "_" + attr.key);
				}
			}
			input.value = switch attr.type {
				case String:
					Std.string(v == null ? attr.getDefaultValue() : v);
				default:
					v == null ? attr.getDefaultValue() : v;
			}
			if (attr.enable == false) {
				input.mouseEnabled = false;
			}
			vbox.addChild(input);
		}
	}

	public function onAttributeChange(attr:IAttributeInput):Void {
		if (editData == null)
			return;

		var oldValue = Reflect.getProperty(editData, attr.key);
		var newValue = attr.value;

		if (oldValue == newValue) {
			// 没有变化，不需要记录历史
			return;
		}

		// 添加历史记录
		var oldValue = {};
		Reflect.setProperty(oldValue, attr.key, Reflect.getProperty(this.editData, attr.key));
		var newValue = {};
		Reflect.setProperty(newValue, attr.key, attr.value);
		EditerStage.historyData.todo(new ChangeAttr(this.editData, oldValue, newValue));

		// 值变更
		Reflect.setProperty(this.editData, attr.key, attr.value);
		switch (attr.key) {
			case "originMoveX", "originMoveY", "originScaleX", "originScaleY", "originRotate", "originAlpha":
				// 需要更新动作位移值
				updateActionData();
			case "isStop", "collision":
				// 需要更新时间轴
				EditerStage.timeline.timelineListView.updateAllData();
		}
		if (title == "特效属性") {
			updateActionData();
		}

		this.dispatchEvent(new Event(Event.CHANGE));
	}

	public function updateActionData():Void {
		// 更新动作数据
		if (EditerStage.timeline.currentActionData != null) {
			EditerStage.timeline.currentActionData.updateActionData();
			EditerStage.timeline.timelineListView.updateAllData();
			EditerStage.world.role.x = EditerStage.world.role.y = 0;
			EditerStage.world.role.playAndStop(EditerStage.timeline.currentActionData.name, EditerStage.world.role.currentFrame);
			EditerStage.objectSelect.update();
		}
	}

	public function updateAttrs():Void {
		bindEditData(this.title, this.editData, this.attrs);
	}
}

@:using(game.utils.AttrDataTools)
typedef AttrData = {
	key:String,
	text:String,
	type:AttrType,
	?defalutValue:Dynamic,
	?enable:Bool,
	?attr:Array<Dynamic>,
	?attrFunc:Void->Array<Dynamic>,
}

enum abstract AttrType(Int) {
	/**
	 * 字符串
	 */
	var String = 0;

	/**
	 * 数字
	 */
	var Number = 1;

	/**
	 * 布尔值
	 */
	var Boolean = 2;

	/**
	 * 碰撞数据
	 */
	var Collision = 4;

	/**
	 * 击中数据
	 */
	var HitData = 5;

	/**
	 * 键盘输入
	 */
	var KeyboardInput = 6;

	/**
	 * 特效输入
	 */
	var EffectInput = 7;

	/**
	 * 对象输入
	 */
	var Object = 8;

	/**
	 * 时间轴输入
	 */
	var Timeline = 9;

	/**
	 * 枚举
	 */
	var Eumes = 10;

	/**
	 * 音频
	 */
	var Sound = 11;
}
